/*********************************************************************************************************************
 * COPYRIGHT NOTICE
 * Copyright (c) 2018,逐飞科技
 * All rights reserved.
 * 技术讨论QQ群：	一群：179029047(已满)
 *					二群：244861897(已满)
 *					三群：824575535
 *
 * 以下所有内容版权均属逐飞科技所有，未经允许不得用于商业用途，
 * 欢迎各位使用并传播本程序，修改内容时必须保留逐飞科技的版权声明。
 *
 * @file			seekfree_mpu6050.c
 * @company			成都逐飞科技有限公司
 * @author			逐飞科技(QQ3184284598)
 * @version			查看doc内version文件 版本说明
 * @Software		IAR 8.3 or MDK 5.24
 * @Taobao			https://seekfree.taobao.com/
 * @date			2020-03-25
 * @note			本文件作为IOT开发板seekfree_mpu6050传感器API
 ********************************************************************************************************************/
#include "seekfree_mpu6050.h"
#include "zf_utick.h"

int16_t mpu_gyro_x,mpu_gyro_y,mpu_gyro_z;
int16_t mpu_acc_x,mpu_acc_y,mpu_acc_z;

//-------------------------------------------------------------------------------------------------------------------
//  @brief      MPU6050自检函数
//  @param      Index			使用的 FlexCOMM 端口
//  @return     void					
//  @since      v1.0
//  Sample usage:				调用该函数前，请先调用模拟IIC的初始化
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
void mpu6050_self1_check(iot_flexcomm_index_list Index)
#else
void mpu6050_self1_check(flexcomm_index_list Index)
#endif
{
	uint8_t mpu6050_states = 0x00;

	zf_iic_write_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, PWR_MGMT_1, 0x00);	//解除休眠状态
	zf_iic_write_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, SMPLRT_DIV, 0x07);   //125HZ采样率
	while(0x07 != mpu6050_states)
	{
		zf_iic_read_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, SMPLRT_DIV, &mpu6050_states, 1);
		delay_ms(100);
		//卡在这里原因有以下几点
		//1 MPU6050坏了，如果是新的这样的概率极低
		//2 接线错误或者没有接好
		//3 可能你需要外接上拉电阻，上拉到3.3V
		//4 可能没有调用模拟IIC的初始化函数
	}
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      初始化MPU6050
//  @param      Index			使用的 FlexCOMM 端口
//  @return     void					
//  @since      v1.0
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
void mpu6050_init(iot_flexcomm_index_list Index)
#else
void mpu6050_init(flexcomm_index_list Index)
#endif
{
	i2c_master_config_t iic_mpu6050_config;									// 定义一个 Flex COMM 配置结构体
	// 初始化 MPU6050 FlexCOMM 接口部分
	zf_iic_master_get_default_config( &iic_mpu6050_config);						// 获取默认设置

#ifdef IOT_BOARD
	iot_flexcomm_init(Index, FLEX_COMM_IIC_MASTER, &iic_mpu6050_config);
#else
	zf_flexcomm_init((flexcomm_index_list)Index, FLEX_COMM_IIC_MASTER, &iic_mpu6050_config);
#endif

	delay_ms(100);																		//上电延时

	mpu6050_self1_check(Index);
	zf_iic_write_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, PWR_MGMT_1,		0x00);				//解除休眠状态
	zf_iic_write_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, SMPLRT_DIV,		0x07);				//125HZ采样率
	zf_iic_write_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, MPU6050_CONFIG,	0x04);				//
	zf_iic_write_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, GYRO_CONFIG,		0x18);				//2000
	zf_iic_write_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, ACCEL_CONFIG,	0x10);				//8g
	zf_iic_write_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, User_Control,	0x00);
	zf_iic_write_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, INT_PIN_CFG,		0x02);
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      获取MPU6050加速度计数据
//  @param      Index			使用的 FlexCOMM 端口
//  @return     void
//  @since      v1.0
//  Sample usage:				执行该函数后，直接查看对应的变量即可
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
void mpu6050_get_accdata(iot_flexcomm_index_list Index)
#else
void mpu6050_get_accdata(flexcomm_index_list Index)
#endif
{
	uint8_t dat[6];

	zf_iic_read_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, ACCEL_XOUT_H, dat, 6);
	mpu_acc_x = (int16_t)(((uint16_t)dat[0]<<8 | dat[1]));
	mpu_acc_y = (int16_t)(((uint16_t)dat[2]<<8 | dat[3]));
	mpu_acc_z = (int16_t)(((uint16_t)dat[4]<<8 | dat[5]));
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      获取MPU6050陀螺仪数据
//  @param      Index			使用的 FlexCOMM 端口
//  @return     void
//  @since      v1.0
//  Sample usage:				执行该函数后，直接查看对应的变量即可
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
void mpu6050_get_gyro(iot_flexcomm_index_list Index)
#else
void mpu6050_get_gyro(flexcomm_index_list Index)
#endif
{
	uint8_t dat[6];

	zf_iic_read_reg((flexcomm_index_list)Index, MPU6050_DEV_ADDR, GYRO_XOUT_H, dat, 6);
	mpu_gyro_x = (int16_t)(((uint16_t)dat[0]<<8 | dat[1]));
	mpu_gyro_y = (int16_t)(((uint16_t)dat[2]<<8 | dat[3]));
	mpu_gyro_z = (int16_t)(((uint16_t)dat[4]<<8 | dat[5]));
}